#include "invocation_matcher.hpp"
#include "test.hpp"
#include "object.hpp"
#include "exact_argument_matcher.hpp"
#include <memory>

using std::tr1::shared_ptr;
using std::vector;

namespace vimock {

struct F {
	object obj;
	object func;
	argument_matcher_vector argument_matchers;
	_invocation_matcher invocation_matcher;
	object_vector args;
	F() :
		obj(1000),
		func(1001),
		argument_matchers(new vector<argument_matcher>()),
		invocation_matcher(obj, func, argument_matchers),
		args(new vector<object>()) {
		object arg1(100);
		args->push_back(arg1);
		argument_matcher argument_matcher1(new exact_argument_matcher(arg1));
		argument_matchers->push_back(argument_matcher1);
	}
};

TEST_SUITE(invoation_matcher_test, F);

TEST_CASE(matches_should_return_false_when_object_different) {
	invocation invocation(new _invocation(0, func, args));
	assert_is_false(invocation_matcher.matches(invocation));
}

TEST_CASE(matches_should_return_false_when_function_different) {
	invocation invocation(new _invocation(obj, 0, args));
	assert_is_false(invocation_matcher.matches(invocation));
}

TEST_CASE(matches_should_return_false_when_argument_count_different) {
	object_vector different_args(new vector<object>());
	invocation invocation(new _invocation(obj, func, different_args));
	assert_is_false(invocation_matcher.matches(invocation));
}

TEST_CASE(matches_should_return_false_when_individual_argument_different) {
	object_vector different_args(new vector<object>());
	different_args->push_back(0);
	invocation invocation(new _invocation(obj, func, different_args));
	assert_is_false(invocation_matcher.matches(invocation));
}

TEST_CASE(matches_should_return_true_when_all_same) {
	invocation invocation(new _invocation(obj, func, args));
	assert_is_true(invocation_matcher.matches(invocation));
}

TEST_SUITE_END();
}
